#
# Copyright (c) 2021, 2023 supercell
#
# SPDX-License-Identifier: BSD-3-Clause
#
require "./luce/ast"
require "./luce/block_parser"
require "./luce/block_syntaxes/alert_block_syntax"
require "./luce/block_syntaxes/block_syntax"
require "./luce/block_syntaxes/blockquote_syntax"
require "./luce/block_syntaxes/code_block_syntax"
require "./luce/block_syntaxes/dummy_block_syntax"
require "./luce/block_syntaxes/empty_block_syntax"
require "./luce/block_syntaxes/fenced_blockquote_syntax"
require "./luce/block_syntaxes/fenced_code_block_syntax"
require "./luce/block_syntaxes/footnote_def_syntax"
require "./luce/block_syntaxes/header_syntax"
require "./luce/block_syntaxes/header_with_id_syntax"
require "./luce/block_syntaxes/horizontal_rule_syntax"
require "./luce/block_syntaxes/html_block_syntax"
require "./luce/block_syntaxes/link_reference_definition_syntax"
require "./luce/block_syntaxes/list_syntax"
require "./luce/block_syntaxes/ordered_list_syntax"
require "./luce/block_syntaxes/ordered_list_with_checkbox_syntax"
require "./luce/block_syntaxes/paragraph_syntax"
require "./luce/block_syntaxes/setext_header_syntax"
require "./luce/block_syntaxes/setext_header_with_id_syntax"
require "./luce/block_syntaxes/table_syntax"
require "./luce/block_syntaxes/unordered_list_syntax"
require "./luce/block_syntaxes/unordered_list_with_checkbox_syntax"
require "./luce/charcode"
require "./luce/document"
require "./luce/emojis"
require "./luce/extension_set"
require "./luce/html_renderer"
require "./luce/inline_parser"
require "./luce/inline_syntaxes/autolink_syntax"
require "./luce/inline_syntaxes/autolink_extension_syntax"
require "./luce/inline_syntaxes/code_syntax"
require "./luce/inline_syntaxes/color_swatch_syntax"
require "./luce/inline_syntaxes/decode_html_syntax"
require "./luce/inline_syntaxes/delimiter_syntax"
require "./luce/inline_syntaxes/email_autolink_syntax"
require "./luce/inline_syntaxes/emoji_syntax"
require "./luce/inline_syntaxes/emphasis_syntax"
require "./luce/inline_syntaxes/escape_html_syntax"
require "./luce/inline_syntaxes/escape_syntax"
require "./luce/inline_syntaxes/image_syntax"
require "./luce/inline_syntaxes/inline_html_syntax"
require "./luce/inline_syntaxes/inline_syntax"
require "./luce/inline_syntaxes/line_break_syntax"
require "./luce/inline_syntaxes/link_syntax"
require "./luce/inline_syntaxes/soft_line_break_syntax"
require "./luce/inline_syntaxes/strikethrough_syntax"
require "./luce/inline_syntaxes/text_syntax"
require "./luce/util"
require "./luce/line"

require "./extern/dart_uri"

# Parses text in a Markdown-like format building an
# [AST tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree)
# that can then be rendered to HTML.
#
# If you are only interested in rendering Markdown to HTML, please refer
# to the [README](../index.html) which explains the use of `Luce.to_html`.
#
# The main entrypoint to the library is the `Document` which
# encapsulates the parsing process converting a Markdown text into
# a tree of `Node` (`Array(Node)`).
#
# The two main parsing mechanics used are:
#
# - Blocks, representing top-level elements
#   implemented via `BlockSyntax` subclasses,
#   such as headers, paragraphs, blockquotes, and code blocks.
# - Inlines, representing chunks of test within a block with special meaning,
#   implemented via `InlineSyntax` subclasses,
#   such as links, emphasis, and inlined code.
#
# Looking closely at `Document.new()` a few other concepts merit a mention:
#
# - `ExtensionSet` that provides configurations for common Markdown flavors
# - `Resolver` which aid in resolving links and images.
#
# If you are looking at extending the library to support custom formatting
# what you might want is to:
#
# - Implement your own `InlineSyntax` subclasses
# - Implement your own `BlockSyntax` subclasses
# - Instruct the library to use those by:
#   - Creating a new `ExtensionSet` from one of the existing flavors
#     and adding your syntaxes.
#   - Passing your syntaxes to `Document` or `Luce.to_html` as parameters.
module Luce
  VERSION = "0.5.0"

  # Converts the given string of Markdown to HTML
  def self.to_html(
    markdown : String,
    block_syntaxes = Array(BlockSyntax).new,
    inline_syntaxes = Array(InlineSyntax).new,
    extension_set : ExtensionSet? = nil,
    link_resolver : Resolver? = nil,
    image_link_resolver : Resolver? = nil,
    inline_only : Bool = false,
    encode_html : Bool = true,
    enable_tag_filter : Bool = false,
    with_default_block_syntaxes : Bool = true,
    with_default_inline_syntaxes : Bool = true
  ) : String
    document = Document.new(block_syntaxes, inline_syntaxes, extension_set, link_resolver, image_link_resolver,
      encode_html, with_default_block_syntaxes, with_default_inline_syntaxes)

    return render_html(document.parse_inline markdown) if inline_only

    nodes = document.parse(markdown)

    "#{self.render_html(nodes, enable_tag_filter: enable_tag_filter)}\n"
  end

  # Render *nodes* to HTML.
  def self.render_html(nodes : Array(Node), enable_tag_filter : Bool = false) : String
    HTMLRenderer.new(enable_tag_filter: enable_tag_filter).render(nodes)
  end
end
